package cc.ttiot.thread.dataTransmissionThread;

import cc.ttiot.enums.SystemConstant;
import cc.ttiot.mapper.dao.ApproachingSwitchMsgMapper;
import cc.ttiot.mapper.dao.SendMsgTimeRecordMapper;
import cc.ttiot.mapper.domain.ApproachingSwitchMsg;
import cc.ttiot.mapper.domain.SendMsgTimeRecord;
import cc.ttiot.mapper.utils.MybatisUtils;
import cc.ttiot.service.dataTransmission.mqtt.Client;
import org.apache.ibatis.session.SqlSession;
import org.eclipse.paho.client.mqttv3.MqttException;

import java.util.List;

import static cc.ttiot.enums.TablesInfo.ApproachingSwitch;
import static cc.ttiot.service.dataTransmission.DataTransmission.transmit;

/**
 * @Description: TODO
 * @Author WangSuheng
 * @Date 2021/10/4 12:27
 * @Version 1.0
 */
public class ApproachingSwitchTransmitThread implements Runnable {
    //数据库初始化
    /*
         1) SqlSession类是线程不安全的，所以每个线程都要有个单独的SqlSession
         2) 下面这种sqlSessionFactory.openSession()的方式获取SqlSession对象默认事务autoCommit设为false，
            所以除了查询语句其他语句执行后要调用sqlSession.commit()方法提交事务
    */

    private final Client client;
    private final SqlSession sqlSession;

    private final ApproachingSwitchMsgMapper asmMapper;

    private final SendMsgTimeRecordMapper strMapper;
    private final SendMsgTimeRecord sendMsgTimeRecord;

    {
        client = Client.getInstance();
        sqlSession = MybatisUtils.getSqlSession();

        asmMapper = sqlSession.getMapper(ApproachingSwitchMsgMapper.class);

        strMapper = sqlSession.getMapper(SendMsgTimeRecordMapper.class);
        sendMsgTimeRecord = new SendMsgTimeRecord();
    }

    public ApproachingSwitchTransmitThread() {
        super();
    }

    @Override
    public void run() {
        //先初始化ID、时间记录
        String lastTime = strMapper.select(ApproachingSwitch.getTableId());
        sendMsgTimeRecord.setId(ApproachingSwitch.getTableId());
        sendMsgTimeRecord.setLastTime(lastTime);

//出现mapper无法获取更新后的数据的问题 博客: https://blog.csdn.net/shenhaiyushitiaoyu/article/details/89243079
//一级缓存与二级缓存问题: https://blog.csdn.net/u014749862/article/details/80297943
//https://tech.meituan.com/2018/01/19/mybatis-cache.html
//  解决方案 : https://cloud.tencent.com/developer/article/1522959

        do {
            //从数据库中取出数据
            List<ApproachingSwitchMsg> msgs = asmMapper.selectByTimeToNow(sendMsgTimeRecord.getLastTime());
            //目前没有新数据
            if (msgs.size() == 0) {
                continue;
//                try {
//                    Thread.currentThread().wait();
//                    continue;
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
            }

            //TODO 客户端始终保持连接状态的情况，考虑能不能优化连接，降低服务器的压力
            if (!client.isConnected()) {
                try {
                    client.connect();
                } catch (MqttException e) {
                    e.printStackTrace();
                }
            }

            try {
                //发数据
                transmit(SystemConstant.APPROACHING_SWITCH_TOPIC, msgs);
                //更新时间
                sendMsgTimeRecord.setLastTime(msgs.get(msgs.size() - 1).getTime());

                strMapper.update(sendMsgTimeRecord);
                sqlSession.commit();

            } catch (MqttException e) {
                e.printStackTrace();
            }
        } while (true);
    }
}
